#include "common_iic.h"

/*============================================================================
 wrapper硬件接口层，移植本文件需要填充所有wrapper函数
 ============================================================================*/
//iic1的sda配置输出模式
static void iic1_wrapper_sda_out()
{
    
}
//iic1的sda配置输入模式
static void iic1_wrapper_sda_in()
{
    
}
//iic1的sda输出低
static void iic1_wrapper_sda_l()
{
    
}
//iic1的sda输出高
static void iic1_wrapper_sda_h()
{
    
}
//获取iic1的sda电平
static uint8_t iic1_wrapper_sda_state()
{
    
}
//iic1的scl输出高
static void iic1_wrapper_scl_h()
{
    
}
//iic1的scl输出低
static void iic1_wrapper_scl_l()
{
    
}
//...继续填充可能存在的iic2、iic3......

//iic的硬件接口注册
static const T_common_iic_line iic_line[IIC_DEV_LINE_CNT] = {
    {
        .sda_out    = iic1_wrapper_sda_out,
        .sda_in     = iic1_wrapper_sda_in,
        .sda_l      = iic1_wrapper_sda_l,
        .sda_h      = iic1_wrapper_sda_h,
        .sda_state  = iic1_wrapper_sda_state,
        .scl_l      = iic1_wrapper_scl_l,
        .scl_h      = iic1_wrapper_scl_h
    },
};

//根据CPU填充微秒延时
void iic_wrapper_dlyUs(uint16_t us)
{
    //nop when HCLK is 160MHz
    while(us--)
    {
        __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
        __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
        __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
        __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
        __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
        __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
        __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
        __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
    }
}

/*============================================================================
 IIC协议底层,硬件变动后不需改动
 驱动关键点:保证每次操作完后(STOP除外)，SCL处于低电平状态
 ============================================================================*/
//iic开始
//line:iic硬件号
void iic_start(uint8_t line)
{
    common_iic.pHw[line].sda_out();;
    common_iic.pHw[line].sda_h();
    iic_wrapper_dlyUs(2);
    common_iic.pHw[line].scl_h();
    iic_wrapper_dlyUs(2);
    common_iic.pHw[line].sda_l();
    iic_wrapper_dlyUs(2);
    common_iic.pHw[line].scl_l();
    iic_wrapper_dlyUs(2);
}
//iic结束
//line:iic硬件号
void iic_stop(uint8_t line)
{
    common_iic.pHw[line].sda_out();;
    common_iic.pHw[line].sda_l();
    iic_wrapper_dlyUs(2);
    common_iic.pHw[line].scl_h();
    iic_wrapper_dlyUs(2);
    common_iic.pHw[line].sda_h();
    iic_wrapper_dlyUs(2);
}
//iic发送ack
//line:iic硬件号
//val:1 ack    0 不acck
void iic_send_ack(uint8_t line,uint8_t val)
{
    common_iic.pHw[line].sda_out();;
    common_iic.pHw[line].scl_l();
    
    if(val == IIC_FALSE)
    {
        common_iic.pHw[line].sda_h();
    }
    else
    {
        common_iic.pHw[line].sda_l();
    }

    iic_wrapper_dlyUs(2);
    common_iic.pHw[line].scl_h();
    iic_wrapper_dlyUs(2);
    common_iic.pHw[line].scl_l();

    common_iic.pHw[line].sda_in();
}
//iic等待ack
//line:iic硬件号
uint8_t iic_wait_ack(uint8_t line)
{
    uint8_t res = IIC_FALSE;
    common_iic.pHw[line].sda_in();
    iic_wrapper_dlyUs(2);
    common_iic.pHw[line].scl_h();
    if(common_iic.pHw[line].sda_state())
    {
        res = IIC_FALSE;
    }
    else
    {
        res = IIC_TRUE;
    }
    iic_wrapper_dlyUs(2);
    common_iic.pHw[line].scl_l();
    return res;
} 
//iic发送字节
//line:iic硬件号
void iic_send_byte(uint8_t line,uint8_t byte)
{
    uint8_t i;
    common_iic.pHw[line].sda_out();;
    for(i = 0;i < 8; i++)
    {
        if(byte & 0x80)
        {
            common_iic.pHw[line].sda_h();
        }
        else
        {
            common_iic.pHw[line].sda_l();
        }
        iic_wrapper_dlyUs(2);
        common_iic.pHw[line].scl_h();
        iic_wrapper_dlyUs(2);
        common_iic.pHw[line].scl_l();
        byte <<= 1;
    }
}
//iic接收字节
//line:iic硬件号
uint8_t iic_rev_byte(uint8_t line)
{
    uint8_t i,byte = 0;
    common_iic.pHw[line].sda_in();
    for(i = 0;i < 8; i++)
    {
        iic_wrapper_dlyUs(2);
        common_iic.pHw[line].scl_h();
        byte <<= 1;
        if(common_iic.pHw[line].sda_state())
        {
            byte |= 1;
        }
        iic_wrapper_dlyUs(2);
        common_iic.pHw[line].scl_l();
    }

    return byte;
}
//iic通用接口注册
const T_common_iic common_iic = {
    .pHw        = iic_line,
    .lineCnt    = IIC_DEV_LINE_CNT,

    .dlyUs      = iic_wrapper_dlyUs,
    .start      = iic_start,
    .stop       = iic_stop,
    .send_ack   = iic_send_ack,
    .wait_ack   = iic_wait_ack,
    .send_byte  = iic_send_byte,
    .rev_byte   = iic_rev_byte
};